//This is the output module responsible for transmitting data across the channel and keeping track of the remaining number of credits

module output_module(clock, data_out, credit_in, valid_out, source_valid, ready_to_source, data_from_source, reset);
	parameter data_width = 34;
	parameter credit_count = 4;
	parameter credit_count_sz = 3;
	parameter addr_count = 32;
	parameter addr_count_sz = 7;
	
	input clock;	
	output wire [data_width-1:0] data_out;
	input credit_in;
	output wire valid_out;
	reg [10:0] credits_total_in;
	input source_valid, reset;
	output wire ready_to_source;
	input [data_width-1:0] data_from_source;
	reg [credit_count_sz:0] credits;

	/* This is functionally the logic for valid out, must re-write for modules	
	assign valid_out = (last_addr == addr) ? 0 : 1;
	*/
	//assign valid_out = (source_valid & ready_to_source);
	assign valid_out = source_valid & ready_to_source;
	//assign ready_to_source = ((credits< 1) & (~credit_in)) ? 0:1;
	assign ready_to_source = (credits > 0) || ((credits == 0) && (credit_in));
	
	assign data_out = data_from_source;


	always @(posedge clock or negedge reset) begin
		if (~reset) begin
			credits <= credit_count-1;
			credits_total_in <= 0;
		end

		else begin
			if(credit_in & source_valid & ready_to_source) // we've sent something off but also received a credit
			        credits <= credits;
			else if(credit_in & ~(source_valid & ready_to_source) )  // we received a credit but didn't send anything
				credits <= credits + 1'b1;
			else if(~credit_in & ~(source_valid & ready_to_source)) //we didn't receive a credit and didn't send anything
				credits <= credits;
			else if(~credit_in & source_valid & ready_to_source) //we sent something but didn't receive any credits
				credits <= credits - 1'b1;	

			
			if (credit_in)
				credits_total_in <= credits_total_in +1;				
		end

	end
	
endmodule
